import { useState, useEffect } from "react"

const ReactVirtualDOMDemo = () => {
  const [showDetails, setShowDetails] = useState(false)
  const [counter, setCounter] = useState(0)
  const [renderTime, setRenderTime] = useState<number | null>(null)

  // 使用一个简单的计时器来模拟测量渲染性能
  useEffect(() => {
    const startTime = performance.now()

    // 假设这是一个复杂的渲染操作
    const timerId = setTimeout(() => {
      const endTime = performance.now()
      setRenderTime(endTime - startTime)
    }, 0)

    return () => clearTimeout(timerId)
  }, [counter])

  // 模拟DOM更新示例1 - 只更新文本节点
  const updateTextOnly = () => {
    setCounter((prevCounter) => prevCounter + 1)
  }

  // 模拟DOM更新示例2 - 添加/移除节点
  const [showExtraElement, setShowExtraElement] = useState(false)
  const toggleExtraElement = () => {
    setShowExtraElement((prev) => !prev)
  }

  // 模拟DOM更新示例3 - 重新排序节点
  const [items, setItems] = useState(["Item 1", "Item 2", "Item 3"])
  const shuffleItems = () => {
    setItems([...items].sort(() => Math.random() - 0.5))
  }

  return (
    <div className="demo-section">
      <h2>React 虚拟 DOM 原理讲解</h2>

      <div className="card">
        <h3>1. 什么是虚拟 DOM?</h3>
        <p>
          虚拟 DOM (Virtual DOM) 是 React 中的一个概念，它是真实 DOM 的内存中的
          JavaScript 对象表示。 React 使用虚拟 DOM 来优化 UI
          更新过程，减少对实际 DOM 的直接操作，提高性能。
        </p>
        <button onClick={() => setShowDetails(!showDetails)}>
          {showDetails ? "隐藏详情" : "显示详情"}
        </button>

        {showDetails && (
          <div className="example-output">
            <h4>虚拟 DOM 的工作流程:</h4>
            <ol>
              <li>
                <strong>初始渲染</strong>: React 创建整个应用的虚拟 DOM 树
              </li>
              <li>
                <strong>虚拟 DOM 转换</strong>: 从虚拟 DOM 生成实际 DOM 并显示
              </li>
              <li>
                <strong>状态变化</strong>: 当应用状态改变时，创建新的虚拟 DOM 树
              </li>
              <li>
                <strong>Diffing</strong>: 比较新旧虚拟 DOM 树，找出差异
              </li>
              <li>
                <strong>批量更新</strong>: 一次性将所有改变应用到实际 DOM
              </li>
            </ol>
          </div>
        )}
      </div>

      <div className="card">
        <h3>2. 常见面试问题: React 的 Diffing 算法原理是什么?</h3>
        <p>React 的 Diffing 算法通过两个假设来实现 O(n) 的复杂度:</p>
        <ul>
          <li>
            <strong>不同类型的元素</strong>: 生成不同的树（销毁旧树，创建新树）
          </li>
          <li>
            <strong>使用 key 属性</strong>:
            帮助识别子元素在不同渲染中是否保持稳定
          </li>
        </ul>

        <div className="code-example">
          <p>Diffing 策略示例:</p>
          <pre>{`// 旧的虚拟DOM树
<div>
  <p>Text</p>
  <Counter count={1} />
</div>

// 新的虚拟DOM树
<div>
  <p>Updated Text</p>
  <Counter count={2} />
</div>

// React 检测到:
// 1. div 元素类型相同，保留
// 2. p 元素类型相同，只更新文本内容
// 3. Counter 组件类型相同，更新 props`}</pre>
        </div>
      </div>

      <div className="card">
        <h3>3. 虚拟 DOM 带来的优势</h3>
        <ul>
          <li>
            <strong>批量更新</strong>: 收集所有变化后一次性更新
            DOM，减少重排与重绘
          </li>
          <li>
            <strong>跨平台</strong>: 虚拟 DOM 抽象层使 React
            能在各种环境中运行（Web、Native）
          </li>
          <li>
            <strong>声明式 API</strong>: 开发者描述 UI 状态，而不是手动操作 DOM
          </li>
          <li>
            <strong>可预测性</strong>: 单向数据流使状态变化更易于追踪
          </li>
        </ul>
      </div>

      <div className="card">
        <h3>4. 演示: 不同类型的 DOM 更新</h3>

        <h4>4.1 只更新文本内容</h4>
        <div className="example-output">
          <p>
            计数器值: <strong>{counter}</strong>
          </p>
          <p>
            上次渲染时间:{" "}
            {renderTime ? `${renderTime.toFixed(2)}ms` : "计算中..."}
          </p>
          <button onClick={updateTextOnly}>更新文本</button>
          <p className="warning">
            当只更新文本内容时，React 只需要修改 DOM
            中的文本节点，这是最高效的更新方式。
          </p>
        </div>

        <h4>4.2 添加/移除节点</h4>
        <div className="example-output">
          <div>
            <p>基本内容永远显示</p>
            {showExtraElement && (
              <div className="card">
                <p>这是条件渲染的内容</p>
                <p>添加或移除整个节点是较为昂贵的操作</p>
              </div>
            )}
            <button onClick={toggleExtraElement}>
              {showExtraElement ? "隐藏额外内容" : "显示额外内容"}
            </button>
          </div>
          <p className="warning">
            添加或移除整个节点子树时，React 需要创建或销毁多个 DOM
            节点，这比仅更新文本内容更昂贵。
          </p>
        </div>

        <h4>4.3 重新排序节点</h4>
        <div className="example-output">
          <ul>
            {items.map((item) => (
              <li key={item}>{item} (使用内容作为key)</li>
            ))}
          </ul>
          <button onClick={shuffleItems}>打乱顺序</button>
          <p className="warning">
            有稳定 key 的列表重新排序时，React 只需移动 DOM
            节点而不是重新创建，这提高了效率。
          </p>
        </div>
      </div>

      <div className="card">
        <h3>5. 常见面试问题: 虚拟 DOM 一定比直接操作 DOM 更快吗?</h3>
        <p>不一定。虚拟 DOM 的优势在于处理频繁更新的复杂 UI，而不是所有场景:</p>
        <ul>
          <li>对于简单 UI 或极少更新的应用，直接操作 DOM 可能更高效</li>
          <li>
            虚拟 DOM 的真正优势是开发效率和代码可维护性，而不仅仅是渲染性能
          </li>
          <li>对于高度优化的动画或拖拽操作，有时直接使用 DOM API 性能会更好</li>
        </ul>
      </div>

      <div className="card">
        <h3>6. 面试核心要点</h3>
        <ul>
          <li>虚拟 DOM 是真实 DOM 的 JavaScript 对象表示</li>
          <li>
            React 使用 Diffing 算法比较新旧虚拟 DOM 树，找出最少需要更新的部分
          </li>
          <li>Reconciliation 是找出两个树差异并决定如何高效更新 UI 的过程</li>
          <li>
            React Fiber 是 React 16
            引入的新协调引擎，允许渲染工作分片并优先处理高优先级更新
          </li>
          <li>使用稳定的 key 可以帮助 React 更高效地更新列表</li>
          <li>虚拟 DOM 主要优势是开发体验和代码可维护性，而不仅仅是性能</li>
        </ul>
      </div>
    </div>
  )
}

export default ReactVirtualDOMDemo
